package com.zbxj.wyz.config;


import com.zbxj.wyz.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@EnableWebSecurity  // 开启security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    /**
     * 用户身份认证自定义配置
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //  密码需要设置编码器
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // 使用UserDetailsService进行身份认证
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }

    /**
     * 在LoginServiceImpl需要用到AuthenticationManager对象进行用户认证
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors();//允许跨域
        http.csrf().disable();//跨域要加上该语句，否则只能获取的get请求，post请求将被拦截（即使加了 .antMatchers("/userLogin").permitAll()语句）
        http.authorizeRequests()
                .antMatchers("/userLogin").permitAll()
                .antMatchers("/**").permitAll()
//                .antMatchers("/artwork").permitAll()
//                .antMatchers("/img/**").permitAll()//放行静态资源
                .anyRequest().authenticated();
        http.formLogin();

        http.logout()
                .logoutUrl("/mylogout")//设置请求/mylogout时执行退出操作
                .logoutSuccessUrl("/logout");

        //把token校验过滤器添加到过滤器链中
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //自定义异常处理类
        http.exceptionHandling().
                authenticationEntryPoint(authenticationEntryPoint);
    }
    //SecurityConfig中配置开启CORS默认会找name为corsConfigurationSource的bean
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        // 提供CorsConfiguration实例，并配置跨域信息
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("token"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("http://127.0.0.1"));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source;
        source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }
}
